<?php
    #-------------------------------------------------------------#
	# This file is part of the Kumomado - Virtual Window Platform #
	# for PHP. (c) 2009 Tsai, Min Che <tirme0812@gmail.com>       #
	# Please visit http://www.kumomado.org/ for more information. #
	#                                                             #
	# This software is licensed under the GNU License v3. Please  #
	# view the LICENSE file for the full text of this license.    #
    #-------------------------------------------------------------#

	define('SQL_SELECT', 'SELECT %s FROM %s WHERE %s');
	define('SQL_INSERT', 'INSERT INTO %s (%s) VALUES(%s)');
	define('SQL_UPDATE', 'UPDATE %s SET %s WHERE %s');
	define('SQL_DELETE', 'DELETE FROM %s WHERE %s');
	define('SQL_LEFTJOIN', ' LEFT JOIN %s ON %s=%s');
	define('SQL_GROUPBY', ' GROUP BY %s');
	define('SQL_UNION', ' UNION %s');
	define('SQL_LIMIT', ' LIMIT %d, %d');
	define('SQL_ORDERBY_ASC', ' ORDER BY %s ASC');
	define('SQL_ORDERBY_DESC', ' ORDER BY %s DESC');
	/**
	 * @package libraries/object/
	 * @author Tsai, Min Che
	 * @version 1.0
	 */
	class KumomadoObjectHandler {
		/**
		 * @var object
		 * @link KumomadoObject
		 */
		public $object;
		/**
		 * @var object
		 * @link KumomadoDatabase
		 */
		protected $db;
		/**
		 * @var string
		 */
		protected $sql;
		/**
		 * @var array
		 */
		protected $select = array();
		/**
		 * @var array
		 */
		protected $table = array();
		/**
		 * @var array
		 */
		protected $join = array();
		/**
		 * @var array
		 */
		protected $where = array();
		/**
		 * @var array
		 */
		protected $limit = array('start' => 0, 'limit' => 0);
		/**
		 * @var array
		 */
		protected $order_by = array('order' => array(), 'sort' => 'DESC');
		/**
		 * @var resource
		 */
		protected $result = null;
		/**
		 *
		 * @param object $object @link KumomadoDataObject
		 * @param string $db_name
		 */
		public function __construct(KumomadoObject $object, $db_name = null) {
			$this->object = $object;
			$this->db = Kumomado::db($db_name);
			return $this->object;
		}
		/**
		 * Reset handler record
		 */
		public function reset() {
			$this->select = array();
			$this->table = array();
			$this->where = array();
			$this->result = null;
			return $this->object;
		}
		public function query($sql) {
			
		}
		protected function _query($start = 0, $limit = 0) {
			$this->result = $this->db->query($this->sql, $start, $limit);
		}
		public function select($select, $alias = '') {
			$this->select[] = array(
				'field' => $select,
				'alias' => $alias
			);
			return $this->object;
		}
		protected function _select() {
			if (count($this->select) == 0) {
				$this->select('*');
			}
			$sql = '';
			foreach ($this->select as $select) {
				$sql .= $select['field'];
				if ($select['alias'] != '') {
					$sql .= ' AS `'.$select['alias'].'`';
				}
				$sql .= ',';
			}
			$sql = preg_replace('/,$/', '', $sql);
			return $sql;
		}
		public function table($table) {
			$this->table[] = $this->db->prefix($table);
			return $this->object;
		}
		protected function _table() {
			if (empty($this->table)) {
				return $this->db->prefix($this->object->getTable());
			} else {
				return join(',', $this->table);
			}
		}
		public function join(KumomadoObject $object, $join_column, $map_column, $direction = 'left') {
			$this->join[] = array(
				'object' => $object,
				'join_column' => $join_column,
				'map_column' => $map_column,
				'direction' => $direction);
			return $this->object;
		}
		public function _join() {
			$sql = '';
			foreach ($this->join as $join) {
				$sql .= sprintf(SQL_LEFTJOIN, $this->db->prefix($join['object']->getTable()), $join['object']->column($join['join_column']), $this->object->column($join['map_column']));
			}
			return $sql;
		}
		public function where($field, $value, $operator = '=', $condition = 'AND') {
			$this->where[] = array(
				'field' => $field,
				'value' => $value,
				'operator' => $operator,
				'condition' => $condition
			);
			return $this->object;
		}
		protected function _where() {
			$sql = '';
			if (count($this->where) == 0) {
				$sql = '1';
			}
			$condition = false;
			foreach ($this->where as $where) {
				if ($condition) {
					$sql .= ' '.$where['condition'].' ';
				}
				$sql .= $where['field'];
				$sql .= $where['operator'];
				$sql .= ' '.$this->db->quoteString($where['value']);
				$condition = true;
			}
			return $sql;
		}
		public function limit($start, $limit) {
			$start = intval($start);
			$limit = intval($limit);
			if ($start >= 0 && $limit > 0) {
				$this->limit['start'] = $start;
				$this->limit['limit'] = $limit;
			}
			return $this->object;
		}
		public function orderBy($order, $sort = 'DESC') {
			if (in_array($order, $this->getFields())) {
				$sort = $sort == 'ASC' ? $sort : 'DESC';
				$this->order_by['order'][] = $order;
				$this->order_by['sort'] = $sort;
			}
			return $this->object;
		}
		protected function _orderBy() {
			$sql = '';
			
		}
		public function groupBy() {
			return $this->object;
		}
		protected function _groupBy() {

		}
		public function column($column) {
			if (in_array($column, $this->object->getFields())) {
				return $this->db->prefix($this->object->getTable()).'.'.$column;
			}
		}
		public function find() {
			$this->sql = sprintf(SQL_SELECT, $this->_select(), $this->_table().$this->_join(), $this->_where());
			return $this->_query($this->limit['start'], $this->limit['limit']);
		}
		public function get() {
			$values = $this->db->fetchArray($this->result);
			return is_array($values) ? $values : false;
		}
		public function fetch() {
			$values = $this->db->fetchArray($this->result);
			if (empty($this->join)) {
				$this->object->setVars($values);
			} else {
				foreach ($this->join as $join) {
					foreach ($join['object']->getFields() as $field) {
						$this->object->addVar($field);
					}
				}
				$this->object->setVars($values);
			}
			return is_array($values);
		}
		/**
		 *
		 * @param int $id
		 * @return object @link KumomadoDataObject
		 */
		public function getById($id) {
			$this->reset();
			$this->where($this->object->getPrimaryKey(), $id);
			$this->limit(0, 1);
			$this->find();
			$this->fetch();
			return $this->object;
		}
		/**
		 *
		 * @return boolean
		 */
		public function insert() {
			$fields = $values = array();
			foreach ($this->object->getVars() as $field => $value) {
				$fields[] = $this->db->quoteSyntax($field);
				$values[] = $this->db->quoteString($value);
			}
			$this->sql = sprintf(SQL_INSERT, $this->_table(), join(',', $fields), join(',', $values));
			$this->_query();
			if ($this->object->getVar($this->object->getPrimaryKey()) == null) {
				$this->object->setVar($this->object->getPrimaryKey(), $this->db->getInsertId());
			}
			return $this->result;
		}
		public function update() {
			$update = array();
			foreach ($this->object->getVars() as $field => $value) {
				if ($value != null && $this->object->getPrimaryKey() != $field) {
					$update[] = $field.'='.$this->db->quoteString($value);
				}
			}
			$this->sql = sprintf(SQL_UPDATE, $this->_table(), join(',', $update), $this->_where());
			$this->_query();
			return $this->result;
		}
		/**
		 *
		 */
		public function count() {
			$this->reset();
			$this->select('COUNT(*)', 'count');
			$this->find();
			$count = $this->get();
			return $count['count'];
		}
		/**
		 *
		 */
		public function delete() {
			$this->sql = sprintf(SQL_DELETE, $this->_table(), $this->_where());
			$this->_query();
			return $this->result;
		}
		public function getSQL() {
			return $this->sql;
		}
	}
?>